﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using Illusion.Extensions;
using UnityEngine;
using UnityEngine.SceneManagement;

namespace Studio
{
	// Token: 0x020004F4 RID: 1268
	public class Scene : Singleton<Scene>
	{
		// Token: 0x170003B0 RID: 944
		// (get) Token: 0x0600202D RID: 8237 RVA: 0x000C8268 File Offset: 0x000C6468
		// (set) Token: 0x0600202E RID: 8238 RVA: 0x000C8270 File Offset: 0x000C6470
		public SimpleFade sceneFade { get; private set; }

		// Token: 0x170003B1 RID: 945
		// (get) Token: 0x0600202F RID: 8239 RVA: 0x000C827C File Offset: 0x000C647C
		// (set) Token: 0x06002030 RID: 8240 RVA: 0x000C8284 File Offset: 0x000C6484
		public GameObject commonSpace { get; private set; }

		// Token: 0x170003B2 RID: 946
		// (get) Token: 0x06002031 RID: 8241 RVA: 0x000C8290 File Offset: 0x000C6490
		// (set) Token: 0x06002032 RID: 8242 RVA: 0x000C8298 File Offset: 0x000C6498
		public UnityEngine.SceneManagement.Scene activeScene
		{
			get
			{
				return SceneManager.GetActiveScene();
			}
			set
			{
				SceneManager.SetActiveScene(value);
			}
		}

		// Token: 0x170003B3 RID: 947
		// (get) Token: 0x06002033 RID: 8243 RVA: 0x000C82A4 File Offset: 0x000C64A4
		public List<string> nowSceneNames
		{
			get
			{
				return this.sceneStack.nowSceneNameList;
			}
		}

		// Token: 0x170003B4 RID: 948
		// (get) Token: 0x06002034 RID: 8244 RVA: 0x000C82B4 File Offset: 0x000C64B4
		public string addSceneName
		{
			get
			{
				if (this.sceneStack.Count > 0)
				{
					Scene.Data data = this.sceneStack.Peek();
					if (data.isAdd)
					{
						return data.sceneName;
					}
				}
				return string.Empty;
			}
		}

		// Token: 0x170003B5 RID: 949
		// (get) Token: 0x06002035 RID: 8245 RVA: 0x000C82F8 File Offset: 0x000C64F8
		// (set) Token: 0x06002036 RID: 8246 RVA: 0x000C8300 File Offset: 0x000C6500
		public static bool isGameEnd { get; private set; }

		// Token: 0x170003B6 RID: 950
		// (get) Token: 0x06002037 RID: 8247 RVA: 0x000C8308 File Offset: 0x000C6508
		public bool isOverlap
		{
			get
			{
				return this.sceneStack.Count > 0 && this.sceneStack.Peek().isOverlap;
			}
		}

		// Token: 0x170003B7 RID: 951
		// (get) Token: 0x06002038 RID: 8248 RVA: 0x000C8330 File Offset: 0x000C6530
		public bool isExit
		{
			get
			{
				return this.addSceneName == "StudioExit";
			}
		}

		// Token: 0x170003B8 RID: 952
		// (set) Token: 0x06002039 RID: 8249 RVA: 0x000C8344 File Offset: 0x000C6544
		public Color fadeColor
		{
			set
			{
				this.sceneFade.SafeProc(delegate(SimpleFade fade)
				{
					fade._Color = value;
				});
			}
		}

		// Token: 0x170003B9 RID: 953
		// (get) Token: 0x0600203A RID: 8250 RVA: 0x000C8378 File Offset: 0x000C6578
		public bool isNowLoading
		{
			get
			{
				if (this.loadStack.Any<Scene.Data>())
				{
					return true;
				}
				return this.sceneStack.Any((Scene.Data v) => v.isLoading || (v.operation != null && !v.operation.isDone));
			}
		}

		// Token: 0x170003BA RID: 954
		// (get) Token: 0x0600203B RID: 8251 RVA: 0x000C83B4 File Offset: 0x000C65B4
		public bool isNowLoadingFade
		{
			get
			{
				return this.isNowLoading || this.sceneFade.IsFadeNow;
			}
		}

		// Token: 0x0600203C RID: 8252 RVA: 0x000C83D0 File Offset: 0x000C65D0
		public void GameEnd(bool _isCheck = true)
		{
			this.isGameEndCheck = _isCheck;
			Application.Quit();
		}

		// Token: 0x0600203D RID: 8253 RVA: 0x000C83E0 File Offset: 0x000C65E0
		public void Load(Scene.Data _data)
		{
			base.StartCoroutine(this.LoadStart(_data));
		}

		// Token: 0x0600203E RID: 8254 RVA: 0x000C83F0 File Offset: 0x000C65F0
		public bool UnLoad()
		{
			if (this.sceneStack.Count <= 1)
			{
				return false;
			}
			Scene.Data scene = this.sceneStack.Peek();
			AsyncOperation asyncOperation = scene.Unload();
			this.sceneStack.Pop();
			Scene.Data.UnloadType unloadType = (asyncOperation == null) ? Scene.Data.UnloadType.Fail : ((!this.nowSceneNames.Any((string s) => s == scene.sceneName)) ? Scene.Data.UnloadType.Success : Scene.Data.UnloadType.Loaded);
			bool flag = false;
			if (unloadType != Scene.Data.UnloadType.Fail)
			{
				if (unloadType == Scene.Data.UnloadType.Loaded)
				{
					flag = true;
				}
			}
			else if (this.addSceneName.IsNullOrEmpty())
			{
				base.StartCoroutine(this.LoadStart(this.sceneStack.Pop()));
			}
			else
			{
				flag = true;
			}
			if (flag)
			{
				do
				{
					this.loadStack.Push(this.sceneStack.Pop());
				}
				while (this.loadStack.Peek().isAdd);
				while (this.loadStack.Any<Scene.Data>())
				{
					Scene.Data data = this.loadStack.Pop();
					bool isAsync = data.isAsync;
					data.isAsync = false;
					this.sceneStack.Push(data);
					data.isAsync = isAsync;
				}
			}
			return true;
		}

		// Token: 0x0600203F RID: 8255 RVA: 0x000C853C File Offset: 0x000C673C
		private void GameExit()
		{
			Scene.isGameEnd = true;
		}

		// Token: 0x06002040 RID: 8256 RVA: 0x000C8544 File Offset: 0x000C6744
		private void CreateSpace()
		{
			UnityEngine.Object.Destroy(this.commonSpace);
			this.commonSpace = new GameObject("CommonSpace");
			UnityEngine.Object.DontDestroyOnLoad(this.commonSpace);
		}

		// Token: 0x06002041 RID: 8257 RVA: 0x000C856C File Offset: 0x000C676C
		private IEnumerator LoadStart(Scene.Data _data)
		{
			if (_data.isFadeIn && !this.sceneFade.IsFadeNow)
			{
				yield return base.StartCoroutine(this.Fade(SimpleFade.Fade.In, null));
				float waitTime = Time.realtimeSinceStartup + 0.1f + _data.fadeInWaitFixedTime;
				yield return new WaitWhile(() => Time.realtimeSinceStartup < waitTime);
			}
			yield return base.StartCoroutine(this.LoadAsync(_data));
			if (this.loadStack.Count == 0)
			{
				Resources.UnloadUnusedAssets();
				if (_data.isFadeOut && this.sceneFade._Fade == SimpleFade.Fade.In)
				{
					float waitTime = Time.realtimeSinceStartup + 0.1f + _data.fadeOutWaitFixedTime;
					yield return new WaitWhile(() => Time.realtimeSinceStartup < waitTime);
					yield return base.StartCoroutine(this.Fade(SimpleFade.Fade.Out, null));
				}
			}
			yield break;
		}

		// Token: 0x06002042 RID: 8258 RVA: 0x000C8590 File Offset: 0x000C6790
		private IEnumerator LoadAsync(Scene.Data _data)
		{
			while (this.isOverlap)
			{
				yield return (!this.isExit) ? base.StartCoroutine(this.UnLoad(false)) : null;
			}
			this.sceneStack.Push(_data);
			if (_data.operation != null)
			{
				while (!_data.operation.isDone)
				{
					yield return null;
				}
			}
			yield break;
		}

		// Token: 0x06002043 RID: 8259 RVA: 0x000C85B4 File Offset: 0x000C67B4
		private IEnumerator UnLoad(bool _isLoadBack)
		{
			if (this.sceneStack.Count <= 1)
			{
				yield break;
			}
			bool isLoadSceneBack = false;
			bool isNowSceneRemove = false;
			if (_isLoadBack)
			{
				isLoadSceneBack = true;
				isNowSceneRemove = true;
			}
			else
			{
				AsyncOperation op = this.sceneStack.Peek().Unload();
				this.sceneStack.Pop();
				if (op != null)
				{
					while (!op.isDone)
					{
						yield return null;
					}
				}
			}
			if (isLoadSceneBack)
			{
				yield return base.StartCoroutine(this.LoadSceneBack(isNowSceneRemove, true));
			}
			yield break;
		}

		// Token: 0x06002044 RID: 8260 RVA: 0x000C85D8 File Offset: 0x000C67D8
		private IEnumerator LoadSceneBack(bool _isNowSceneRemove, bool _isAddSceneLoad)
		{
			if (_isNowSceneRemove && this.sceneStack.Count > 1)
			{
				this.sceneStack.Pop();
			}
			do
			{
				this.loadStack.Push(this.sceneStack.Pop());
			}
			while (this.loadStack.Peek().isAdd);
			while (this.loadStack.Count > 0)
			{
				Scene.Data data = this.loadStack.Pop();
				if (!_isAddSceneLoad)
				{
					this.loadStack.Clear();
				}
				yield return base.StartCoroutine(this.LoadStart(data));
			}
			yield break;
		}

		// Token: 0x06002045 RID: 8261 RVA: 0x000C8604 File Offset: 0x000C6804
		private IEnumerator Fade(SimpleFade.Fade _fade, Action _fadeWaitProc = null)
		{
			this.sceneFade.FadeSet(_fade, -1f, null);
			while (!this.sceneFade.IsEnd)
			{
				yield return null;
				_fadeWaitProc.Call();
			}
			yield break;
		}

		// Token: 0x06002046 RID: 8262 RVA: 0x000C8630 File Offset: 0x000C6830
		protected override void Awake()
		{
			if (!base.CheckInstance())
			{
				return;
			}
			UnityEngine.Object.DontDestroyOnLoad(base.gameObject);
			AssetBundleLoadAssetOperation assetBundleLoadAssetOperation = AssetBundleManager.LoadAsset("scene/scenemanager.unity3d", "scenemanager", typeof(GameObject), null);
			GameObject asset = assetBundleLoadAssetOperation.GetAsset<GameObject>();
			GameObject gameObject = UnityEngine.Object.Instantiate<GameObject>(asset);
			gameObject.name = asset.name;
			gameObject.transform.SetParent(base.transform, false);
			this.sceneFade = gameObject.GetComponentInChildren<SimpleFade>();
			this.sceneFade._Fade = SimpleFade.Fade.Out;
			this.sceneFade.ForceEnd();
			this.CreateSpace();
			Scene.isGameEnd = false;
			this.isGameEndCheck = true;
			this.isSkipGameExit = false;
			this.sceneStack = new Scene.SceneStack<Scene.Data>(new Scene.Data
			{
				sceneName = this.activeScene.name,
				isAdd = false
			});
			this.loadStack = new Stack<Scene.Data>();
		}

		// Token: 0x06002047 RID: 8263 RVA: 0x000C8714 File Offset: 0x000C6914
		private void OnApplicationQuit()
		{
			if (this.isSkipGameExit)
			{
				Application.CancelQuit();
				return;
			}
			if (this.isGameEndCheck)
			{
				this.isGameEndCheck = false;
				bool flag = true;
				flag &= !this.isExit;
				flag &= !Application.isEditor;
				if (flag)
				{
					Application.CancelQuit();
					this.Load(new Scene.Data
					{
						sceneName = "StudioExit",
						isAdd = true,
						isOverlap = true
					});
					this.isSkipGameExit = true;
				}
				else
				{
					this.GameExit();
				}
			}
			else
			{
				this.GameExit();
			}
		}

		// Token: 0x040021F8 RID: 8696
		private const float FadeWaitFixedTime = 0.1f;

		// Token: 0x040021F9 RID: 8697
		private SceneStack<Scene.Data> sceneStack;

		// Token: 0x040021FA RID: 8698
		private Stack<Scene.Data> loadStack;

		// Token: 0x040021FB RID: 8699
		public bool isGameEndCheck;

		// Token: 0x040021FC RID: 8700
		public bool isSkipGameExit;

		// Token: 0x020004F5 RID: 1269
		public class Data
		{
			// Token: 0x170003BB RID: 955
			// (set) Token: 0x0600204A RID: 8266 RVA: 0x000C87EC File Offset: 0x000C69EC
			public bool isFade
			{
				set
				{
					this.fadeType = ((!value) ? Scene.Data.FadeType.None : Scene.Data.FadeType.InOut);
				}
			}

			// Token: 0x170003BC RID: 956
			// (get) Token: 0x0600204B RID: 8267 RVA: 0x000C8804 File Offset: 0x000C6A04
			public bool isFadeIn
			{
				get
				{
					return this.fadeType == Scene.Data.FadeType.InOut || this.fadeType == Scene.Data.FadeType.In;
				}
			}

			// Token: 0x170003BD RID: 957
			// (get) Token: 0x0600204C RID: 8268 RVA: 0x000C8820 File Offset: 0x000C6A20
			public bool isFadeOut
			{
				get
				{
					return this.fadeType == Scene.Data.FadeType.InOut || this.fadeType == Scene.Data.FadeType.Out;
				}
			}

			// Token: 0x170003BE RID: 958
			// (get) Token: 0x0600204D RID: 8269 RVA: 0x000C883C File Offset: 0x000C6A3C
			// (set) Token: 0x0600204E RID: 8270 RVA: 0x000C8844 File Offset: 0x000C6A44
			public AsyncOperation operation { get; private set; }

			// Token: 0x0600204F RID: 8271 RVA: 0x000C8850 File Offset: 0x000C6A50
			public AsyncOperation Unload()
			{
				if (!this.isAdd)
				{
					return null;
				}
				return SceneManager.UnloadSceneAsync(this.sceneName);
			}

			// Token: 0x06002050 RID: 8272 RVA: 0x000C886C File Offset: 0x000C6A6C
			public void Load()
			{
				if (this.isAsync)
				{
					this.operation = SceneManager.LoadSceneAsync(this.sceneName, (!this.isAdd) ? LoadSceneMode.Single : LoadSceneMode.Additive);
				}
				else
				{
					SceneManager.LoadScene(this.sceneName, (!this.isAdd) ? LoadSceneMode.Single : LoadSceneMode.Additive);
				}
			}

			// Token: 0x04002201 RID: 8705
			public string sceneName = string.Empty;

			// Token: 0x04002202 RID: 8706
			public bool isOverlap;

			// Token: 0x04002203 RID: 8707
			public bool isAdd;

			// Token: 0x04002204 RID: 8708
			public bool isAsync;

			// Token: 0x04002205 RID: 8709
			public bool isLoading;

			// Token: 0x04002206 RID: 8710
			public float fadeInWaitFixedTime;

			// Token: 0x04002207 RID: 8711
			public float fadeOutWaitFixedTime;

			// Token: 0x04002208 RID: 8712
			public Scene.Data.FadeType fadeType;

			// Token: 0x020004F6 RID: 1270
			public enum FadeType
			{
				// Token: 0x0400220B RID: 8715
				None,
				// Token: 0x0400220C RID: 8716
				InOut,
				// Token: 0x0400220D RID: 8717
				In,
				// Token: 0x0400220E RID: 8718
				Out
			}

			// Token: 0x020004F7 RID: 1271
			public enum UnloadType
			{
				// Token: 0x04002210 RID: 8720
				Success,
				// Token: 0x04002211 RID: 8721
				Fail,
				// Token: 0x04002212 RID: 8722
				Loaded
			}
		}

		// Token: 0x020004F8 RID: 1272
		public class SceneStack<T> : Stack<T> where T : Scene.Data
		{
			// Token: 0x06002051 RID: 8273 RVA: 0x000C88CC File Offset: 0x000C6ACC
			public SceneStack(T item)
			{
				base.Push(item);
				this.nowSceneNameList.Push(item.sceneName);
			}

			// Token: 0x170003BF RID: 959
			// (get) Token: 0x06002052 RID: 8274 RVA: 0x000C88FC File Offset: 0x000C6AFC
			public List<string> nowSceneNameList
			{
				get
				{
					return this._nowSceneNameList;
				}
			}

			// Token: 0x06002053 RID: 8275 RVA: 0x000C8904 File Offset: 0x000C6B04
			public new void Push(T item)
			{
				base.Push(item);
				if (!item.isAdd)
				{
					this.nowSceneNameList.Clear();
				}
				this.nowSceneNameList.Push(item.sceneName);
				item.Load();
			}

			// Token: 0x06002054 RID: 8276 RVA: 0x000C8958 File Offset: 0x000C6B58
			public new T Pop()
			{
				T result = base.Pop();
				if (this.nowSceneNameList.Any<string>())
				{
					this.nowSceneNameList.Pop<string>();
				}
				if (!this.nowSceneNameList.Any<string>())
				{
					foreach (T t in this)
					{
						this.nowSceneNameList.Add(t.sceneName);
						if (!t.isAdd)
						{
							break;
						}
					}
				}
				return result;
			}

			// Token: 0x04002213 RID: 8723
			private List<string> _nowSceneNameList = new List<string>();
		}
	}
}
